package wangn.adt;

import wangn.adt.base.More;
import wangn.adt.base.Pair;
import wangn.adt.base.Tri;

import java.util.*;

//n叉树的一个节点
public class ItemSetNode{
    private int state;

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
    }

    /**
     * Tri(CFG第几项，点在哪一个字符的前面,检测符)
     */
    private List<Tri<Integer,Integer, More<Character>>> itemList;

    public ItemSetNode(int state){
        this.state = state;
        itemList = new ArrayList<>();
    }

    public Tri<Integer,Integer,More<Character>> getItem(int idx){
        return idx>=itemList.size()?null:itemList.get(idx);
    }

    public void setItem(int idx, Tri<Integer,Integer,More<Character>> lr1item){
        itemList.set(idx,lr1item);
    }

    public int getLength(){return itemList.size();}

    public void addItem(int grammarIdx, int dotPosition,More<Character> checkFlags){
        Tri<Integer,Integer,More<Character>> tri = new Tri<>(grammarIdx,dotPosition,checkFlags);
        itemList.add(tri);
    }

    private Map<Character,ItemSetNode> childrenMap = new HashMap<>();//goto(state,Character)
    private List<Character> childrenList = new ArrayList<>();//存储所有孩子的名号也就是状态转移的字符

    public void addChild(char name, ItemSetNode itemSetNode){
        childrenMap.put(name,itemSetNode);
        if (!childrenList.contains(name))childrenList.add(name);
    }

    public ItemSetNode getChild(char transferChar){
        return childrenMap.getOrDefault(transferChar,null);
    }

    public List<ItemSetNode> getChildren(){return new ArrayList<>(childrenMap.values());}

    public void setChild(char transferChar, ItemSetNode itemSetNode){childrenMap.put(transferChar,itemSetNode);}

    public List<Character> getChildrenTranferChars(){return childrenList;}

    //为了比较两个node的文法以及状态还有检测符是否相等
    //简单利用三元组的字面值（序号的升序）直接拼接成hash值，下同
    public String getRealHashValue(){
        return getHashValue(false);
    }

    //不包含检测符
    public String getSimpleHashValue(){
        return getHashValue(true);
    }

    private String getHashValue(boolean isSimple){
        int itemLength = getLength();
        String[] sbs = new String[itemLength];
        int sbs_idx = 0;
        for (int i = 0; i < itemLength; i++){
            Tri<Integer,Integer,More<Character>> tri = getItem(i);
            if (isSimple){
                sbs[sbs_idx++] = tri.getFirst()+","+tri.getSecond();
            }else{
                sbs[sbs_idx++] = tri.toString();
            }
        }
        Arrays.sort(sbs);
        StringBuilder sb = new StringBuilder();
        for (String str : sbs){
            sb.append(str);
            sb.append(",");
        }
        sb.deleteCharAt(sb.length()-1>=0?sb.length()-1:0);
        return sb.toString();
    }

    public Pair<Integer,Tri<Integer,Integer,More<Character>>> getItem(int grammarIdx, int dotPosition){
        for (int i = 0; i < itemList.size(); i++){
            Tri<Integer,Integer,More<Character>> tri = itemList.get(i);
            if (tri.getFirst()==grammarIdx && tri.getSecond()==dotPosition)return new Pair<>(i,tri);
        }
        return null;
    }
}
